﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CoreGallery.Core.Data;
using CoreGallery.Addins.Contracts;
using System.Configuration;

namespace CoreGallery.Core.PhotoMgr
{
    /// <summary>
    /// Core storage abstraction for all photos housed in CoreGallery
    /// </summary>
    public class PhotoManager
    {
        // The index is the provider-neutral common index of media data
        // Provider-specific and generic metadata is stored along with thumbnails and app-required data
        private CoreGalleryIndex db = null;

        // The providers actually store the full-size media
        private List<IStorageProviderBase> _providers = new List<IStorageProviderBase>();

        public event EventHandler<CoreMediaEventArgs<BasePhoto>> PhotoAddedEvent;
        public event EventHandler<CoreMediaEventArgs<BasePhoto>> PhotoRemovedEvent;
        public event EventHandler<CoreMediaEventArgs<BasePhoto>> PhotoUpdatedEvent;

        public event EventHandler<CoreMediaEventArgs<BaseGallery>> GalleryAddedEvent;
        public event EventHandler<CoreMediaEventArgs<BaseGallery>> GalleryRemovedEvent;
        public event EventHandler<CoreMediaEventArgs<BaseGallery>> GalleryUpdatedEvent;

        public event EventHandler<CoreMediaEventArgs<BaseAlbum>> AlbumAddedEvent;
        public event EventHandler<CoreMediaEventArgs<BaseAlbum>> AlbumRemovedEvent;
        public event EventHandler<CoreMediaEventArgs<BaseAlbum>> AlbumUpdatedEvent;

        private static object _lock = new object();
        private static PhotoManager mgr;

        public PhotoManager()
        {
            string sdfPath = ConfigurationManager.ConnectionStrings["CoreGallery.Core.Properties.Settings.CoreGalleryIndexConnectionString"].ConnectionString;

            db = new CoreGalleryIndex(sdfPath);

            if (System.Diagnostics.Debugger.IsAttached) db.Log = Console.Out;
            #if debug


            #endif
        }

        public static PhotoManager GetInstance()
        {
            lock (_lock)
            {
                if (mgr == null) mgr = new PhotoManager();
            }

            return mgr;
        }

        /// <summary>
        /// Called by a given provider to add photo info to the storage engine
        /// </summary>
        /// <param name="newphoto"></param>
        public void AddPhoto(BasePhoto newphoto)
        {
            CoreMediaEventArgs<BasePhoto> e = new CoreMediaEventArgs<BasePhoto>(newphoto);

            // TODO: Extract metadata and thumbnail to store
            if (PhotoAddedEvent != null)
                PhotoAddedEvent(this, e);
        }

        public void RemovePhoto(BasePhoto photo)
        {
            // TODO: Use UniqueId as key and remove references

            if( PhotoRemovedEvent != null )
                PhotoRemovedEvent(this, new CoreMediaEventArgs<BasePhoto>(photo));
        }

        public void UpdatePhoto(BasePhoto updatedPhoto)
        {
            // TODO: Use UniqueId as key and update metadata
            if (PhotoUpdatedEvent != null)
                PhotoUpdatedEvent(this, new CoreMediaEventArgs<BasePhoto>(updatedPhoto));
        }

        public BasePhoto RetrievePhoto(Guid uniqueKey)
        {
            return null;// db.CoreObjects.Where(t => t.ObjectGuid == uniqueKey).Select(t => t);
        }

        public void CreateGallery(BaseGallery newGallery)
        {
            // TODO: Create gallery, persist to index
            if (GalleryAddedEvent != null)
                GalleryAddedEvent(this, new CoreMediaEventArgs<BaseGallery>(newGallery));
        }

        public void CreateAlbum(BaseAlbum newAlbum)
        {
            // TODO: Create album, persist to index
            if (AlbumAddedEvent != null)
                AlbumAddedEvent(this, new CoreMediaEventArgs<BaseAlbum>(newAlbum));
        }

        /// <summary>
        /// Perform a search.  Need to decide how criteria is passed in, how results are paged (iterator yield?), etc.
        /// </summary>
        /// <returns></returns>
        public IList<BasePhoto> Search()
        {
            return null;
        }

        public IList<IStorageProviderBase> Providers
        {
            get { return _providers; }
        }

        /// <summary>
        /// Condition, Operator, Value
        /// </summary>

        public IList<BaseGallery> Galleries
        {
            get {
                return null;// db.CoreGalleries.OrderBy(t => t.GalleryName).Select(t => t);
            }
        }

        public IList<BaseAlbum> Albums
        {
            get { return null; }// db.CoreAlbums.OrderBy(t => t.AlbumName).Select(t => t); }
        }

        public IList<BaseAlbum> GetAlbums(BaseGallery gallery)
        {
            return null;// db.CoreAlbums.Where(t => t.CoreGalleries == gallery).OrderBy(t => t.AlbumName).Select(t => t);
        }

        public IList<BasePhoto> GetPhotos(BaseAlbum album)
        {
            return null;// db.CoreObjects.Where(t => t.CoreAlbums == album).Select(t => t);
        }

        /// <summary>
        /// Collection of all known keywords
        /// </summary>
        public IList<string> Keywords
        {
            get { return null; }
        }
    }
}
